Refresh live previews, add ⌘F search, and harden screen capture#11
Merged
Refresh live previews, add ⌘F search, and harden screen capture#11
Conversation
The cached CGImage from the previous close was being painted as hasRenderedFrame=true, which short-circuited snapshot() on the next show — so the user saw a stale frame until the live stream's first significant-change frame arrived (or forever, for idle windows). Drop the short-circuit so snapshot() always captures a fresh image, kick off snapshot+stream in parallel with the show animation instead of waiting 210ms, and stop gating the display path on the dirty-rect threshold (keep it only for the idle-dot signal) so the tile keeps tracking the source as frames arrive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Search mode filters tiles by substring on app name + window title; return commits the filter, esc / Cancel clears it. Snapshot resolution now scales with the tile's on-screen footprint (live capture unchanged) so dense grids stay light while sparse grids look noticeably sharper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Return picks the highlighted tile, esc / Done commits the filter (rename from Cancel matches the new behaviour), and the cardinal arrow keys move the tile selection instead of the caret. Swallow all caret- movement selectors so the cursor never moves inside the field. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Swift-async overload of captureImage force-unwraps the bridged CGImage?, so a (nil, nil) reply from ScreenCaptureKit traps the process. Wrap the completion-handler form in a continuation and surface a thrown error instead, letting the existing catch log and skip the snapshot. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ScreenCaptureKit can stop a stream on its own (window minimised, source app suspended, replayd churn, backpressure) without us recovering. The tile was left holding a recycled IOSurface and the live preview went dead until the overlay was re-shown. Recover by clearing the dead stream, promoting the last pixel buffer to a stable CGImage so the tile keeps a valid image, and rescheduling start() with a linear backoff up to six attempts. The retry counter resets whenever a fresh frame arrives. Add structured logging for every transition and a per-stream watchdog so we can tell the difference between "stream stopped", "stream alive but only emitting idle/blank/suspended", and "stream alive, complete frames flowing but the layer never updates". Errors are formatted with their NSError domain/code/underlying so the cause is visible in /tmp/cmdcmd.log. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
beginZoom drove layer.frame from the small grid cell to a near-fullsize target while shadowPath snapped to the destination size at t=0, so the blue accent shadow extended to the final dimensions before the tile had moved — reading as a phantom halo. CALayer does not return a default action for shadowPath, so removing the disable-actions wrapper alone wasn't enough; the path is now driven by an explicit CABasicAnimation that mirrors the active transaction's duration and timing function. While peeked, the selected tile's accent border and blue glow are also faded to zero (and restored on endZoom) so the highlight doesn't overwhelm the near-fullscreen preview. Also silence the unused-result warning on FileHandle.seekToEnd in Log. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
peterp
added a commit
that referenced
this pull request
May 1, 2026
Cover the crash fix, live-preview auto-restart, and peek polish that landed in #11, and extend the search changeset to mention arrow-key forwarding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
🤖 Generated with Claude Code